package ch.poole.openinghoursfragment.pickers;

import ch.poole.openinghoursfragment.ResourceTable;
import ch.poole.openinghoursfragment.pickers.dialogpicker.DialogPickerView;
import ch.poole.openinghoursfragment.pickers.dialogpicker.NumberPickerView;
import ch.poole.openinghoursparser.Month;
import ch.poole.openinghoursparser.WeekDay;
import ch.poole.openinghoursparser.YearRange;
import com.lxj.xpopup.impl.ConfirmPopupView;
import com.lxj.xpopup.interfaces.OnConfirmListener;
import ohos.app.Context;
import ohos.data.distributed.common.Value;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;

/**
 * Display a dialog allowing the user to select values for a start date and optionally an end date
 */
public class OccurrenceInMonthPicker {
    private static final int MAX_YEAR = 2100;

    public static final int NOTHING_SELECTED = Integer.MIN_VALUE;

    private static final String TITLE = "title";
    private static final String YEAR = "startYear";
    private static final String MONTH = "startMonth";
    private static final String WEEKDAY = "weekday";
    private static final String OCCURRENCE = "occurrence";

    private static SetDateRangeListener listener;
    private static final String TAG = "fragment_occurrenceinmonthpicker";
    private static String[] monthEntries;
    private static String[] weekdayEntries;
    private static ConfirmPopupView popupView;
    private static String[] yearValues;
    private static String[] occurrenceValues;
    private static NumberPickerView npvYear;
    private static NumberPickerView npvMonth;
    private static NumberPickerView npvWeekday;
    private static NumberPickerView npvOccurrence;

    /**
     * Show the DateRangePicker dialog
     *
     * @param context       context
     * @param title         title
     * @param year          year
     * @param month         mouth
     * @param weekday       weekday
     * @param occurrence    occurrence
     * @param rangeListener rangeListener
     * @throws IOException
     */
    public static void showDialog(Context context, int title, int year, @Nullable Month month, @Nullable WeekDay weekday, int occurrence, SetDateRangeListener rangeListener) {
        try {
            final String titleStr = context.getResourceManager().getElement(title).getString();
            newInstance(context, titleStr, year, month, weekday, occurrence, rangeListener);
            if (popupView != null) {
                popupView.show();
            }
        } catch (IOException | NotExistException | WrongTypeException e) {
            e.printStackTrace();
        }
    }

    /**
     * Create a new instance of OccurrenceInMonthPicker
     *
     * @param context       context
     * @param title         resource id for the title to display
     * @param year          initial year
     * @param month         initial month
     * @param weekday       initial weekday
     * @param occurrence    initial occurrence
     * @param rangeListener rangeListener
     * @return an instance of OccurrenceInMonthPicker
     * @throws IOException
     */
    private static OccurrenceInMonthPicker newInstance(Context context, String title, int year, @Nullable Month month, @Nullable WeekDay weekday, int occurrence, SetDateRangeListener rangeListener) {
        OccurrenceInMonthPicker f = new OccurrenceInMonthPicker();
        listener = rangeListener;
        yearValues = new String[MAX_YEAR - YearRange.FIRST_VALID_YEAR + 2];
        yearValues[0] = "-";
        for (int i = YearRange.FIRST_VALID_YEAR; i <= MAX_YEAR; i++) {
            yearValues[i - YearRange.FIRST_VALID_YEAR + 1] = Integer.toString(i);
        }


        try {
            monthEntries = context.getResourceManager().getElement(ResourceTable.Strarray_months_entries).getStringArray();
            weekdayEntries = context.getResourceManager().getElement(ResourceTable.Strarray_weekdays_entries).getStringArray();
        } catch (IOException | NotExistException | WrongTypeException e) {
            e.printStackTrace();
        }

        occurrenceValues = new String[10];
        for (int i = -5; i <= 5; i++) {
            occurrenceValues[i > 0 ? i + 4 : i + 5] = "[" + Integer.toString(i) + "]";
        }

        popupView = DialogPickerView.getInstance(context, title, "OK",ResourceTable.Layout_dialog_occurrence_in_month_picker, new OnConfirmListener() {

            @Override
            public void onConfirm() {
                int yearValue = getYearValue(npvYear);
                Month monthValue = getMonthValue(npvMonth);
                WeekDay weekday = getWeekdayValue(npvWeekday);
                int occurrenceValue = getOccurrenceValue(npvOccurrence);

                listener.setDateRange(yearValue, monthValue, weekday, occurrenceValue,null, NOTHING_SELECTED, null, null, NOTHING_SELECTED,null);

            }

            private Month getMonthValue(final NumberPickerView npvMonth) {
                Month monthValue = Month.values()[0];
                if (npvMonth.getValue() != 0) {
                    monthValue = Month.values()[npvMonth.getValue()];
                }
                return monthValue;
            }

            private WeekDay getWeekdayValue(final NumberPickerView npvWeekday) {
                WeekDay weekdayValue = WeekDay.values()[0];
                if (npvWeekday.getValue() != 0) {
                    weekdayValue = WeekDay.values()[npvWeekday.getValue()];
                }
                return weekdayValue;
            }
            private int getYearValue(final NumberPickerView npvYear) {
                int yearValue = npvYear.getValue();
                int returnValue;
                if (yearValue == 0) {
                    returnValue = NOTHING_SELECTED;
                } else {
                    returnValue = yearValue + YearRange.FIRST_VALID_YEAR - 1;
                }
                return returnValue;
            }

            private int getOccurrenceValue(final NumberPickerView npvDay) {
                int occurrence = npvDay.getValue();
                if (occurrence <= 4) {
                    return occurrence - 5;
                }
                return occurrence - 4;
            }

        }, null).build();
        initDialogView(year, month, weekday, occurrence);

        return f;
    }


    private static void initDialogView(int year, @Nullable Month month, @Nullable WeekDay weekday, int occurrence) {
        if (popupView != null) {
            npvYear = (NumberPickerView) popupView.findComponentById(ResourceTable.Id_year);
            npvYear.setDisplayedData(yearValues);
            npvYear.setMinValue(0);
            npvYear.setMaxValue(yearValues.length - 1);
            npvYear.setValue(year != YearRange.UNDEFINED_YEAR ? getYearValue(year) : 0);

            npvMonth = (NumberPickerView) popupView.findComponentById(ResourceTable.Id_month);
            npvMonth.setDisplayedData(monthEntries);
            npvMonth.setMinValue(0);
            npvMonth.setMaxValue(11);
            npvMonth.setValue(month.ordinal());

            npvWeekday = (NumberPickerView) popupView.findComponentById(ResourceTable.Id_weekday);
            npvWeekday.setDisplayedData(weekdayEntries);
            npvWeekday.setMinValue(0);
            npvWeekday.setMaxValue(6);
            npvWeekday.setValue(weekday.ordinal());

            npvOccurrence = (NumberPickerView) popupView.findComponentById(ResourceTable.Id_occurrence);
            npvOccurrence.setDisplayedData(occurrenceValues);
            npvOccurrence.setMinValue(0);
            npvOccurrence.setMaxValue(9);
            npvOccurrence.setValue(occurrence < 0 ? occurrence + 5 : occurrence + 4);
        }
    }

    private static int getYearValue(int year) {
        int Value = 0;
        if (yearValues == null || yearValues.length == 0) {
            Value = 0;
        } else {
            for (int i = 0; i < yearValues.length; i++) {
                if (yearValues[i].equals("" + year)) {
                    Value = i;
                    break;
                }
            }
        }
        return Value;
    }

}
